using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing.Text;
using DG.Tweening;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[Serializable]
public class KeySpritePair
{
    public Keys key;
    public Sprite sprite;
}

public class InputCounter : MonoBehaviour
{
    private TextMeshProUGUI _text;
    private RectTransform _rectTrans;
    public static Dictionary<string, Sprite> keyNameSpriteMap;

    public static Dictionary<Keys, string> keySpNameMap = new Dictionary<Keys, string>()
    {
        {Keys.A, "a"}, {Keys.B, "b"}, {Keys.C, "c"}, {Keys.D, "d"}, {Keys.E, "e"}, {Keys.F, "f"}, {Keys.G, "g"}, {Keys.H, "h"}, {Keys.I, "i"}, {Keys.J, "j"}, {Keys.K, "k"}, {Keys.L, "l"}, {Keys.M, "m"}, {Keys.N, "n"}, {Keys.O, "o"}, {Keys.P, "p"}, {Keys.Q, "q"}, {Keys.R, "r"}, {Keys.S, "s"}, {Keys.T, "t"}, {Keys.U, "u"}, {Keys.V, "v"}, {Keys.W, "w"}, {Keys.X, "x"}, {Keys.Y, "y"}, {Keys.Z, "z"},
        {Keys.Num0, "0"}, {Keys.Num1, "1"}, {Keys.Num2, "2"}, {Keys.Num3, "3"}, {Keys.Num4, "4"}, {Keys.Num5, "5"}, {Keys.Num6, "6"}, {Keys.Num7, "7"}, {Keys.Num8, "8"}, {Keys.Num9, "9"},
        {Keys.Escape, "esc"}, {Keys.OEM3, "~"}, {Keys.Tab, "tab"}, {Keys.CapsLock, "capslock"}, {Keys.LeftShift, "shift"}, {Keys.RightShift, "shift"},  {Keys.LeftCtrl, "ctrl"}, {Keys.RightCtrl, "ctrl"},
        {Keys.LeftMenu, "alt"}, {Keys.RightMenu, "alt"}, {Keys.LeftWin, "win"}, {Keys.RightWin, "win"}, {Keys.Space, "space"}, {Keys.BackSpace, "backspace"}, {Keys.Enter, "enter"},
        {Keys.LeftMouseBtn, "ml"}, {Keys.RightMouseBtn, "mr"}, {Keys.MidMouseBtn, "mm"},
        {Keys.F1, "f1"}, {Keys.F2, "f2"}, {Keys.F3, "f3"}, {Keys.F4, "f4"}, {Keys.F5, "f5"}, {Keys.F6, "f6"}, {Keys.F7, "f7"}, {Keys.F8, "f8"}, {Keys.F9, "f9"}, {Keys.F10, "f10"}, {Keys.F11, "f11"}, {Keys.F12, "f12"},
    };
    
    void Start()
    {
        _text = this.gameObject.GetComponent<TextMeshProUGUI>();
        _rectTrans = this.gameObject.GetComponent<RectTransform>();

        _text.text = GlobalKeyboardListener.Instance.totalClickCount.ToString();
        GlobalKeyboardListener.Instance.AddKeyDownHandler(OnKeyDown);
    }

    void OnDestroy()
    {
        GlobalKeyboardListener.Instance?.RemoveKeyDownHandler(OnKeyDown);
    }

    private void OnKeyDown(Keys key){
        var keySprite = GetSpriteByKey(key);
        if (keySprite != null && GameSetting.Instance.settingData.showFloatKeys){
            CreateFloatKeys(keySprite);
        }
        else {
            DOTween.Kill(_text);
            _text.color = new Color(1f, 1f, 1f, 1f);
            _text.DOFade(0, 0.8f).SetDelay(5).Play();
            _text.text = GlobalKeyboardListener.Instance.totalClickCount.ToString();

            DOTween.Kill(_rectTrans);
            _rectTrans.localScale = Vector3.one * 0.8f;
            _rectTrans.DOScale(Vector3.one, 0.5f).SetEase(Ease.OutBack).Play();
        }
    }

    private void CreateFloatKeys(Sprite keySprite){
        var prefab = Resources.Load<GameObject>("Prefabs/UI/ImageFloatKey");
        var floatText = Instantiate(prefab, _rectTrans.parent);
        
        floatText.GetComponent<Image>().sprite = keySprite;
        floatText.GetComponent<Image>().SetNativeSize();
        floatText.GetComponent<Image>().color = new Color(1f, 1f, 1f, 0.8f);

        var angle = UnityEngine.Random.Range(0, 180) * Mathf.Deg2Rad;
        var distance = UnityEngine.Random.Range(100f, 200f);
        var randomPos = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * distance;
        var rectTrans = floatText.GetComponent<RectTransform>();
        rectTrans.localPosition = randomPos;
        rectTrans.localScale = Vector3.zero;

        Sequence seq = DOTween.Sequence();
        seq.Append(rectTrans.DOScale(Vector3.one * 0.4f / GameSetting.Instance.settingData.size, 0.5f).SetEase(Ease.OutBack));
        seq.AppendInterval(0.2f);
        seq.Append(rectTrans.DOLocalMove(_rectTrans.localPosition, 1f).SetEase(Ease.InExpo));
        seq.Join(rectTrans.GetComponent<Image>().DOFade(0, 1f).SetEase(Ease.InExpo));
        seq.AppendCallback(()=>{
            _text.text = (int.Parse( _text.text) + 1).ToString();
            DOTween.Kill(_text);
            _text.color = new Color(1f, 1f, 1f, 1f);
            _text.DOFade(0, 0.8f).SetDelay(5).Play();

            DOTween.Kill(_rectTrans);
            _rectTrans.localScale = Vector3.one * 0.8f;
            _rectTrans.DOScale(Vector3.one, 0.5f).SetEase(Ease.OutBack).Play();
        });
        seq.onComplete = () => {
            Destroy(floatText);
        };
        seq.Play();
    }

    public static Sprite GetSpriteByKey(Keys key)
    {
        if (keyNameSpriteMap == null)
        {
            keyNameSpriteMap = new Dictionary<string, Sprite>();
            var sprites = Resources.LoadAll<Sprite>("UI/all_input");
            foreach (var sprite in sprites)
            {
                keyNameSpriteMap.TryAdd(sprite.name, sprite);
            }
        }
        keySpNameMap.TryGetValue(key, out var spriteName);
        if (spriteName != null)
        {
            keyNameSpriteMap.TryGetValue(spriteName, out var sprite);
            return sprite;
        }
        return null;
    }
}